package com.freesky.provider.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.freesky.common.dao.entity.Member;
import com.freesky.common.exception.EMallException;
import com.freesky.common.pojo.DataTablesResult;
import com.freesky.common.redis.IRedisTemplate;
import com.freesky.common.vo.VOMember;
import com.freesky.provider.member.service.IMemberService;
import com.freesky.provider.member.util.VOUtil;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.*;

/**
 * @author Freesky
 * @date 2017/8/11
 */
@Service
@Slf4j
public class MemberServiceImpl implements IMemberService {
    @Value("${SESSION_EXPIRE}")
    private Integer SESSION_EXPIRE;

    @Autowired
    private IRedisTemplate redisTemplate;

    @Override
    public Member getMemberById(long memberId) {

        Member member = new Member();
        member.setId(memberId);
        member = member.selectById();
        if (member == null) {
            throw new EMallException("ID获取会员信息失败");
        }
        member.setPassword("");
        return member;
    }

    @Override
    public DataTablesResult getMemberList(int draw, int start, int length, String search,
                                          String minDate, String maxDate, String orderCol, String orderDir) {

        DataTablesResult result = new DataTablesResult();

        try {
            //分页
            boolean asc = false;
            if (orderDir.equalsIgnoreCase("asc")) {
                asc = true;
            }
            Page<Member> memberPage = new Page<>();
            search = "%" + search + "%";
            if (minDate != null && minDate.length() > 0 && maxDate != null && maxDate.length() > 0) {
                memberPage = new Member().selectPage(new Page<>(start / length + 1, length), new EntityWrapper<Member>()
                        .ne("state", 2).and()
                        .between("created", minDate, maxDate).and()
                        .like("username", search).or()
                        .like("phone", search).or()
                        .like("email", search).or()
                        .like("sex", search).or()
                        .like("address", search)
                        .orderBy(orderCol, asc));
            } else {
                memberPage = new Member().selectPage(new Page<>(start / length + 1, length), new EntityWrapper<Member>()
                        .ne("state", 2).and()
                        .like("username", search).or()
                        .like("phone", search).or()
                        .like("email", search).or()
                        .like("sex", search).or()
                        .like("address", search)
                        .orderBy(orderCol, asc));
            }

            List<Member> list = memberPage.getRecords();
            result.setRecordsFiltered(memberPage.getTotal());
            result.setRecordsTotal(memberPage.getSize());

            result.setDraw(draw);
            result.setData(list);
        } catch (Exception e) {
            log.error("加载用户列表失败",e);
            throw new EMallException("加载用户列表失败");
        }

        return result;
    }

    @Override
    public DataTablesResult getRemoveMemberList(int draw, int start, int length, String search,
                                                String minDate, String maxDate, String orderCol, String orderDir) {

        DataTablesResult result = new DataTablesResult();
        search = "%" + search + "%";
        try {
            //分页
            boolean asc = false;
            if (orderDir.equalsIgnoreCase("asc")) {
                asc = true;
            }
            Page<Member> memberPage = new Page<>();
            if (minDate != null && minDate.length() > 0 && maxDate != null && maxDate.length() > 0) {
                memberPage = new Member().selectPage(new Page<>(start / length + 1, length), new EntityWrapper<Member>()
                        .ne("state", 2).and()
                        .between("created", minDate, maxDate).and()
                        .like("username", search).or()
                        .like("phone", search).or()
                        .like("email", search).or()
                        .like("sex", search).or()
                        .like("address", search)
                        .orderBy(orderCol, asc));
            } else {
                memberPage = new Member().selectPage(new Page<>(start / length + 1, length), new EntityWrapper<Member>()
                        .ne("state", 2).and()
                        .like("username", search).or()
                        .like("phone", search).or()
                        .like("email", search).or()
                        .like("sex", search).or()
                        .like("address", search)
                        .orderBy(orderCol, asc));
            }
            result.setRecordsFiltered(memberPage.getTotal());
            result.setRecordsTotal(memberPage.getSize());

            result.setDraw(draw);
            result.setData(memberPage.getRecords());
        } catch (Exception e) {
            log.error("加载删除用户列表失败",e);
            throw new EMallException("加载删除用户列表失败");
        }

        return result;
    }

    @Override
    public Member getMemberByUsername(String username) {
        Member member = new Member().selectOne(new EntityWrapper().eq("username", username));
        if (member==null) {
            throw new EMallException("ID获取会员信息失败");
        }else{
            member.setPassword("");
            return member;
        }
    }

    @Override
    public Member getMemberByPhone(String phone) {

        Member member = new Member().selectOne(new EntityWrapper().eq("phone", phone));
        if (member==null) {
            throw new EMallException("Phone获取会员信息失败");
        }else{
            member.setPassword("");
            return member;
        }
    }

    @Override
    public Member getMemberByEmail(String email) {
        Member member = new Member().selectOne(new EntityWrapper().eq("email", email));
        if (member==null) {
            throw new EMallException("Phone获取会员信息失败");
        }else{
            member.setPassword("");
            return member;
        }
    }

    @Override
    public DataTablesResult getMemberCount() {
        DataTablesResult result = new DataTablesResult();
        int count = new Member().selectCount(new EntityWrapper().eq("state", 2));
        result.setRecordsTotal(count);
        return result;
    }

    @Override
    public DataTablesResult getRemoveMemberCount() {
        DataTablesResult result = new DataTablesResult();
        int count = new Member().selectCount(new EntityWrapper().eq("state", 2));
        result.setRecordsTotal(count);
        return result;
    }

    @Override
    public Member addMember(VOMember voMember) {
        Member member = VOUtil.changeVOMemberToMember(voMember);
        if (getMemberByUsername(member.getUsername()) != null) {
            throw new EMallException("用户名已被注册");
        }
        if (getMemberByPhone(member.getPhone()) != null) {
            throw new EMallException("手机号已被注册");
        }
        if (getMemberByEmail(member.getEmail()) != null) {
            throw new EMallException("邮箱已被注册");
        }

        member.setState(1);
        member.setCreated(new Date());
        member.setUpdated(new Date());
        String md5Pass = DigestUtils.md5DigestAsHex(member.getPassword().getBytes());
        member.setPassword(md5Pass);

        boolean insert = member.insert();
        if (!insert) {
            throw new EMallException("添加用户失败");
        }
        return getMemberByPhone(member.getPhone());
    }

    @Override
    public Member updateMember(Long id, VOMember voMember) {

        Member member = VOUtil.changeVOMemberToMember(voMember);
        member.setId(id);
        member.setUpdated(new Date());
        Member oldMember = getMemberById(id);
        member.setState(oldMember.getState());
        member.setCreated(oldMember.getCreated());
        if (member.getPassword() == null || member.getPassword() == "") {
            member.setPassword(oldMember.getPassword());
        } else {
            String md5Pass = DigestUtils.md5DigestAsHex(member.getPassword().getBytes());
            member.setPassword(md5Pass);
        }
        boolean update = member.updateById();
        if (!update) {
            throw new EMallException("更新会员信息失败");
        }
        return member;
    }

    @Override
    public Member changePassMember(Long id, VOMember voMember) {

        Member member = new Member(id);
        member=member.selectById();

        String md5Pass = DigestUtils.md5DigestAsHex(voMember.getPassword().getBytes());
        member.setPassword(md5Pass);
        member.setUpdated(new Date());
        boolean update = member.updateById();
        if (!update) {
            throw new EMallException("修改会员密码失败");
        }
        return member;
    }

    @Override
    public Member alertMemberState(Long id, Integer state) {
        Member member = new Member(id);
        member=member.selectById();
        member.setState(state);
        member.setUpdated(new Date());
        boolean update = member.updateById();
        if (!update) {
            throw new EMallException("修改会员状态失败");
        }
        return member;
    }

    @Override
    public int deleteMember(Long id) {
        Member member = new Member(id);
        boolean delete = member.deleteById();
        if (!delete) {
            throw new EMallException("删除会员失败");
        }
        return 0;
    }

    @Override
    public Member getMemberByEditEmail(Long id, String email) {
        Member member = new Member(id);
        member=member.selectById();
        Member newMember = null;
        if (member.getEmail() == null || !member.getEmail().equals(email)) {
            newMember = getMemberByEmail(email);
        }
        newMember.setPassword("");
        return newMember;
    }

    @Override
    public Member getMemberByEditPhone(Long id, String phone) {
        Member member = new Member(id);
        member=member.selectById();
        Member newMember = null;
        if (member.getPhone() == null || !member.getPhone().equals(phone)) {
            newMember = getMemberByPhone(phone);
        }
        newMember.setPassword("");
        return newMember;
    }

    @Override
    public Member getMemberByEditUsername(Long id, String username) {
        Member member = new Member(id);
        member=member.selectById();
        Member newMember = null;
        if (member.getUsername() == null || !member.getUsername().equals(username)) {
            newMember = getMemberByUsername(username);
        }
        newMember.setPassword("");
        return newMember;
    }

    @Override
    public String imageUpload(Long userId, String token, String imgData) {
        Member member = new Member();
        member.setId(userId);
        member = member.selectById();
        if (member == null) {
            throw new EMallException("通过id获取用户失败");
        }
        member.setFile(imgData);
        boolean update = member.updateById();
        if (! update) {
            throw new EMallException("更新用户头像失败");
        }

        //更新缓存
        com.freesky.common.vo.portal.VOMember voMember = getUserByToken(token);
        voMember.setFile(imgData);
        redisTemplate.putCache("SESSION:" + token, JSON.toJSON(voMember));
        return imgData;
    }

    @Override
    public boolean checkData(String param, int type) {
        //1：用户名 2：手机号 3：邮箱
        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("state",1);
        if (type == 1) {
            queryMap.put("username",param);
        } else if (type == 2) {
            queryMap.put("phone",param);
        } else if (type == 3) {
            queryMap.put("email",param);
        } else {
            return false;
        }
        List<Member> list = new Member().selectList(new EntityWrapper().allEq(queryMap));
        if (list != null && list.size() > 0) {
            return false;
        }
        return true;
    }

    @Override
    public int register(String userName, String userPwd) {

        Member member = new Member();
        member.setUsername(userName);

        if (userName.isEmpty() || userPwd.isEmpty()) {
            return -1; //用户名密码不能为空
        }
        boolean result = checkData(userName, 1);
        if (!result) {
            return 0; //该用户名已被注册
        }

        //MD5加密
        String md5Pass = DigestUtils.md5DigestAsHex(userPwd.getBytes());
        member.setPassword(md5Pass);
        member.setState(1);
        member.setCreated(new Date());
        member.setUpdated(new Date());
        boolean insert = member.insert();
        if (!insert) {
            throw new EMallException("注册用户失败");
        }
        return 1;
    }
    @Override
    public com.freesky.common.vo.portal.VOMember userLogin(String username, String password) {

        List<Member> list = new Member().selectList(new EntityWrapper().eq("state", 1).eq("username", username));
        if (list == null || list.size() == 0) {
            com.freesky.common.vo.portal.VOMember voMember =new com.freesky.common.vo.portal.VOMember();
            voMember.setState(0);
            voMember.setMessage("用户名或密码错误");
            return voMember;
        }
        Member member = list.get(0);
        //md5加密
        if (!DigestUtils.md5DigestAsHex(password.getBytes()).equals(member.getPassword())) {
            com.freesky.common.vo.portal.VOMember voMember =new com.freesky.common.vo.portal.VOMember();
            voMember.setState(0);
            voMember.setMessage("用户名或密码错误");
            return voMember;
        }
        String token = UUID.randomUUID().toString();
        com.freesky.common.vo.portal.VOMember voMember = VOUtil.MemerToVOMember(member);
        voMember.setToken(token);
        voMember.setState(1);
        // 用户信息写入redis：key："SESSION:token" value："user"
        redisTemplate.putCache("SESSION:" + token, new Gson().toJson(voMember));
        redisTemplate.expire("SESSION:" + token, SESSION_EXPIRE);
        return voMember;
    }

    @Override
    public com.freesky.common.vo.portal.VOMember getUserByToken(String token) {
        String json = redisTemplate.getCacheObject("SESSION:" + token,String.class);
        if (json==null) {
            com.freesky.common.vo.portal.VOMember voMember =new com.freesky.common.vo.portal.VOMember();
            voMember.setState(0);
            voMember.setMessage("用户登录已过期");
            return voMember;
        }
        //重置过期时间
        redisTemplate.expire("SESSION:" + token, SESSION_EXPIRE);
        com.freesky.common.vo.portal.VOMember voMember = new Gson().fromJson(json, com.freesky.common.vo.portal.VOMember.class);
        return voMember;
    }

    @Override
    public int logout(String token) {
        redisTemplate.delete("SESSION:" + token);
        return 1;
    }
}
